import json,os

import dns.set
from flask_login import login_user, login_required, current_user, login_fresh
import requests
from flask import Blueprint,request,redirect,make_response,Response,render_template
from moviepy.editor import VideoFileClip
from application.models.model import *
from swaager_init import siwa,BaseModel
from application.models.model import *
from tools.data_tools import orm2dict,ret_route,limit_framt
from sqlalchemy import text


course_data = siwa.blueprint("course", __name__)

@course_data.route("/get_course",methods=['get'])
def course():
    # 获取前端的数据
    data = dict(request.args)
    # 指定分页根据什么排序
    order = request.args.get('order')
    # 查看是否上限
    online = int(request.args.get('online_status',1))
    # 查看分类
    cate = request.args.get('cate')
    # 标签
    tag = json.loads(request.args.get('tags','[]'))
    # 这个感觉是上面的那个data，前端输入每页限制和从第几页开始
    limit,offset = limit_framt(data)
    # 前端的数据
    serach = request.args.get('serach',None)

    if not order:
        # 将课程排序分页
        data = Course.query.order_by(text('-sort_num')).limit(4).all()
        return ret_route(200,orm2dict(data))
    # 处理分页，通过判断课程是否上限来筛选
    sql =  Course.query.filter_by(online_status=online)
    if cate:
        # 通过分类查出
        sql = sql.filter_by(cate=cate)

    if serach:
        # 最左匹配原则：联合索引
        sql =Course.query.filter(Course.name.like(f"%{serach}%"))
        return ret_route(data=orm2dict(sql))

    if not order:
        data = Course.query.order_by(text('-sort_num')).limit(4).all()
        return ret_route(data=orm2dict(data))

    if tag:
        sql = sql.filter(course_tag.c.tag_id.in_(tag))
    data = sql.order_by(text(order)).limit(limit).offset(offset * limit)
    # join表，两个表连接，筛选出来数据排序
    # data = sql.join(course_tag,course_tag.c.course_id == Course.id)\
    #     .filter().order_by(text(order)).limit(limit).offset(
    #     offset * limit).all()
    return ret_route(200,data=orm2dict(data))

# 方法一：实现
# @course_data.route("/<int:course_id>", methods=['get'])
# def course_info(course_id):
#     # 后去后端指定的课程
#     course = Course.query.get(course_id)
#     # 将获取的数据转换成字典
#     data = orm2dict(course)
#     # 筛选出来课程对应的章节
#     chapters = orm2dict(course.chapter_id)
#     # 重新赋值
#     data['chapters'] = chapters
#     try:
#         # 从用户所看的课程章节中筛选出用户
#         db.session.query(user_course_chapter).filter_by(
#            user_course_chapter.c.user_id==current_user.id,
#            #  讲用户所看的所有的章节全部取出
#            user_course_chapter.c.chapter_id.in_([i.id for i in course.chapter_id])).all()
#         # 用户的章节
#         user_chapters = set(i.id for i in current_user.chapters) & set([i.get('id') for i in chapters])
#         # 用户的章节如果存在，直接转换成列表，输出
#         data['user_chapters'] = list(user_chapters)
#     except Exception as e:
#         print(e)
#         # 没有的话就输出一个空的列表给前端
#         data['user_chapters'] = []
#     # 返回响应结果
#     return ret_route(200,data=orm2dict(course))

# 方法二：
@course_data.route("/<int:course_id>", methods=['GET'])
def course_info(course_id):
    course = Course.query.get(course_id)
    data = orm2dict(course)
    chapters = orm2dict(course.chapter_id)
    data['chapters'] = chapters
    try:
        user_chapters = db.session.query(user_course_chapter)\
        .filter(user_course_chapter.c.user_id == current_user.id,
                user_course_chapter.c.chapter_id.in_([i.id for i in course.chapter_id])).all()
        data['user_chapters'] = [i[0] for i in user_chapters]
    except Exception as e:
        print(e)
        data['user_chapters'] = []
    data['teacher'] = orm2dict(course.teacher)
    return ret_route(data=data)

# 评论
@course_data.route('/<int:course_id>/comment',methods=['get'])
def get_comment(course_id):
    # 筛选出课程
    course = Course.query.get(course_id)
    # CourseComment
    # 字典推导式推出当前课程的评论
    comments_dict = {comment.id : orm2dict(comment) for comment in course.comment_id}
    comments = []

    # 循环遍历字典
    for c_id,comment in comments_dict.items():
        # 跟评论添加到最终字典里
        if not comment['reply_id']:
            comments.append(comment)
            # 如果有跟评论，就先跳过，执行下面的步骤
            continue

        #如果不是根评论，找到子评论的父级评论,如果什么都没有，就添加
        if not comments_dict[comment['reply_id']].get('son',None):
            # 把评论变成空列表
            comments_dict[comment['reply_id']]['son'] = []

        # 将子评论写到父评论下
        comments_dict[comment['reply_id']]['son'].append(comment)

    return ret_route(data=comments_dict)

# 抖音的实现
@course_data.route('/<int:course_id>/douyin',methods=['get'])
def get_douyin(course_id):
    # 筛选出课程
    course = Course.query.get(course_id)
    # CourseComment
    # 字典推导式推出当前课程的评论
    comments_dict = {comment.id: orm2dict(comment) for comment in course.comment_id}
    comments = []
    for comment in comments_dict.values():
        if not comment['root_id']:
            comment['son'] = []
            comments.append(comment)
            continue

        作者 = CourseComment.query.get(comment['reply_id']).author
        comment['to_user_id'] = 作者.id
        comment['to_user_name'] = 作者.nikename
        comments_dict[comment['root_id']]['son'].append(comment)

    return ret_route(data=comments)

# 获取视频
@course_data.route('/<int:course_id>/<int:chapter_id>',methods=['get'])
def get_movies(course_id,chapter_id):
    chapter = Chapter.query.get(chapter_id)
    if login_fresh():
        current_user.bean += 10
        db.session.commit()
    return render_template('templates.html',movie=orm2dict(chapter))

# 老师上传视频
@course_data.route('/gg/<int:course_id>/chapter_id',methods=['post'])
@login_required
def post_movies(course_id):
    teacher = Role.query().filter_by(name='老师').one()
    if teacher not in current_user.role:
        return ret_route(401)
    # 前端传来的数据(可以是视频或者图片文件)
    movie = dict(request.form)
    #获取文件数据
    file = request.files.get('movie')
    # 文件的路径添加进指定的课程
    path = os.path.join(f'./static/movies/',str(course_id))
    # 判断文件的路径在不在你所指定的路径
    if not os.path.isfile(path):
        # os.mkdir() 方法用于以数字权限模式创建目录（单级目录）
        os.mkdir(path)
    # 将接受的数据合成一个文件
    movie_path = os.path.join(path,file.filename)
    # 如果在指定的文件路径
    if os.path.isfile(movie_path):
        return ret_route(201)
    #保存
    file.save(movie_path)
    # Python中moviepy模块，是视频剪辑最基础的模块
    clip = VideoFileClip(movie_path)
    movie['duration'] = int(clip.duration)
    movie['course_id'] = course_id
    movie['path'] = movie_path[1:]
    chapter = Chapter(**movie)
    db.session.add(chapter)
    db.session.commit()
    clip.close()
    return ret_route(200)

# lock = True
# @course_data.route('/collect/<int:course_id>',methods=['post'])
# @login_required
# def get_user_order(course_id):
#     global lock
#     # 找用户和课程
#     user = User.query.get(1)
#     while 1:
#         if lock:
#             lock = False
#             # 找课程加用户
#             course = Course.query.get(course_id)
#             user.collect_course.append(course)
#             #给课程
#             Course.query.filter_by(id=course_id).update({'collect_num':course.collect_num + 1})
#             db.session.commit()
#             break
#     lock = True
#     return ret_route(200)

@course_data.route('/collect/<int:course_id>',methods=['post'])
@login_required
def get_user_order(course_id):
    # 找用户和课程
    user = User.query.get(current_user.id)
    # 找课程加用户
    course = Course.query.get(course_id)
    # 取消收藏
    if course in user.user_order:
        user.user_order.remove(course)
        Course.query.filter_by(id=course_id).update({'collect_num': Course.collect_num - 1})
        db.session.commit()
        return ret_route(200,{'msg':'取消收藏成功'})
    user.user_order.append(course)
    #给课程
    Course.query.filter_by(id=course_id).update({'collect_num':Course.collect_num + 1})
    db.session.commit()
    return ret_route(200)

